package org.me.marble;

import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;

/**
*
* @author tungi
*/

public class Cuboid extends AvailableObject{
	private int from;
	private float width;
	private FloatBuffer frontBuffer,backBuffer,blanketBuffer1,
						blanketBuffer2,blanketBuffer3,blanketBuffer4;
    private FloatBuffer frontTextureBuffer,backTextureBuffer;

    public Cuboid(int id,float width,int from){
        super(id);
        this.from=from;
        this.width=width;
        this.mwidth=width+0.25f;
    }
    
    @Override
    public void setNormal(Path path){
    	Vector proj=null;
    	Vector direction=new Vector();
    	Vector v=new Vector(centre);v.setY(0);
        for(int i=0;i<path.triangles.size();++i){
            if(path.triangles.get(i).isPartProj(v)){
                if(i%2==0){
                	if(from==0)
                		direction=Vector.Minus(
                				path.triangles.get(i).getPoint(1),
                                path.triangles.get(i).getPoint(0));
                	if(from==1)
                		direction=Vector.Minus(
                				path.triangles.get(i+1).getPoint(0),
                                path.triangles.get(i+1).getPoint(1));
                }
                else{
                	if(from==0)
                		direction=Vector.Minus(
                				path.triangles.get(i-1).getPoint(1),
                                path.triangles.get(i-1).getPoint(0));
                	if(from==1)
                		direction=Vector.Minus(
                				path.triangles.get(i).getPoint(0),
                                path.triangles.get(i).getPoint(1));
                }                
                direction.Normalize();
                up=path.triangles.get(i).getNormal();
                proj=Geometry.getProjectionToPlane(up,new Vector(),up);
                break;
            }
        }
        dir_angle=-MyMath.RadtoDegree(Math.acos(Geometry.getCosAngle(
        		new Vector(direction.getX(),0,direction.getZ()),new Vector(0,0,-1))));
        d=Geometry.rotateVector(Math.PI/2,proj,up);
        //if vector is a null vector (this means, that the plane normal is (0,1,0))
        //the normalize operation give us a (NaN,NaN,NaN) vector, which unusable
        if(!Vector.Equal(d,new Vector()))d.Normalize();
        angle=MyMath.RadtoDegree(Math.acos(Geometry.getCosAngle(up,new Vector(0,1,0))));
    }

    @Override
    public void effect(GameRenderer _renderer,MoveMarble _mm){
        _mm.modifySpeed(0.1f);
        //add runnable, time calculated with the measure of the cuboid
        _renderer.addRunnable(timerTypes.block.ordinal(),(int)(width*500f));
    }

    @Override
    public void init(){
        float[] front_side={-width,0.3f,width/2,
                            width,0.3f,width/2,
                            -width,-0.3f,width/2,
                            width,-0.3f,width/2
        };
        float[] back_side={-width,0.3f,-width/2,
                           -width,-0.3f,-width/2,
                           width,0.3f,-width/2,
                           width,-0.3f,-width/2
        };
        float[] blanket1={-width,0.3f,-width/2,
                          -width,0.3f,width/2,
                          -width,-0.3f,-width/2,
                          -width,-0.3f,width/2
        };
        float[] blanket2={-width,-0.3f,-width/2,
                		  -width,-0.3f,width/2,
                          width,-0.3f,-width/2,
                          width,-0.3f,width/2
        };
        float[] blanket3={width,0.3f,width/2,
                		  width,0.3f,-width/2,
                          width,-0.3f,width/2,
                          width,-0.3f,-width/2
        };
        float[] blanket4={-width,0.3f,width/2,
                		  -width,0.3f,-width/2,
                          width,0.3f,width/2,
                          width,0.3f,-width/2
        };
        float[] fronttextures={0.0f,1.0f, 1.0f,1.0f, 0.0f,0.0f, 1.0f,0.0f};
        float[] backtextures={0.0f,1.0f, 0.0f,0.0f, 1.0f,1.0f, 1.0f,0.0f};

        frontBuffer=BufferFactory.MakeFloatBuffer(front_side);
        backBuffer=BufferFactory.MakeFloatBuffer(back_side);
        blanketBuffer1=BufferFactory.MakeFloatBuffer(blanket1);
        blanketBuffer2=BufferFactory.MakeFloatBuffer(blanket2);
        blanketBuffer3=BufferFactory.MakeFloatBuffer(blanket3);
        blanketBuffer4=BufferFactory.MakeFloatBuffer(blanket4);
        frontTextureBuffer=BufferFactory.MakeFloatBuffer(fronttextures);
        backTextureBuffer=BufferFactory.MakeFloatBuffer(backtextures);

        color=new MyColor();
        color.setAmbient(new float[]{1.0f,1.0f,1.0f,1.0f});
        color.setDiffuse(new float[]{1.0f,1.0f,1.0f,1.0f});
        color.setSpecular(new float[]{0.6f,0.6f,0.6f,1.0f});
        color.setEmission(new float[]{0.1f,0.1f,0.1f,1.0f});
        color.setShininess(1.0f);
    }
    
    @Override
    public void draw(GL10 gl){
    	gl.glTranslatef(centre.getX(),centre.getY(),centre.getZ());
        gl.glRotatef(dir_angle,up.getX(),up.getY(),up.getZ());
        gl.glRotatef(angle,d.getX(),d.getY(),d.getZ());

        OpenGLSystem.enable(gl,OpenGLSystem.CULL_FACE | OpenGLSystem.TEXTURE);
        OpenGLSystem.enableClientStates(gl,OpenGLSystem.NORMAL_ARRAY |
                OpenGLSystem.VERTEX_ARRAY | OpenGLSystem.TEXTURE_ARRAY);

        OpenGLSystem.setMaterial(gl,color);

        OpenGLSystem.drawTriangles(gl,texture,frontBuffer,frontBuffer,
                frontTextureBuffer,4,GL10.GL_TRIANGLE_STRIP);
        OpenGLSystem.drawTriangles(gl,texture,backBuffer,backBuffer,
                backTextureBuffer,4,GL10.GL_TRIANGLE_STRIP);
        
        OpenGLSystem.drawTriangles(gl,texture,blanketBuffer1,blanketBuffer1,
        		frontTextureBuffer,4,GL10.GL_TRIANGLE_STRIP);
        OpenGLSystem.drawTriangles(gl,texture,blanketBuffer2,blanketBuffer2,
        		frontTextureBuffer,4,GL10.GL_TRIANGLE_STRIP);
        OpenGLSystem.drawTriangles(gl,texture,blanketBuffer3,blanketBuffer3,
        		frontTextureBuffer,4,GL10.GL_TRIANGLE_STRIP);
        OpenGLSystem.drawTriangles(gl,texture,blanketBuffer4,blanketBuffer4,
        		frontTextureBuffer,4,GL10.GL_TRIANGLE_STRIP);

        OpenGLSystem.disableClientStates(gl,OpenGLSystem.NORMAL_ARRAY | 
                OpenGLSystem.VERTEX_ARRAY | OpenGLSystem.TEXTURE_ARRAY);
        OpenGLSystem.disable(gl,OpenGLSystem.CULL_FACE | OpenGLSystem.TEXTURE);
    }
}
